package cn.angis.system.config.interceptor;

import cn.angis.common.annotation.SLog;
import cn.angis.common.constant.Constant;
import cn.angis.system.model.Log;
import cn.angis.system.service.LogService;
import org.noear.snack.ONode;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject;
import org.noear.solon.annotation.Mapping;
import org.noear.solon.core.handle.Action;
import org.noear.solon.core.handle.Context;
import org.noear.solon.core.handle.Handler;
import org.noear.solon.core.route.RouterInterceptor;
import org.noear.solon.core.route.RouterInterceptorChain;
import org.noear.solon.core.wrap.MethodWrap;

import java.util.StringJoiner;

/**
 * @author angis.cn
 * @Date 2023/2/14 21:17
 */
@Component
public class LogInterceptor implements RouterInterceptor {
    @Inject
    private LogService logService;

//    @QzRateLimit()   //全局限流
    @Override
    public void doIntercept(Context ctx, Handler mainHandler, RouterInterceptorChain chain) throws Throwable {
        chain.doIntercept(ctx, mainHandler);
    }

    @Override
    public Object postResult(Context ctx, Object result) throws Throwable {
        Object controller = ctx.controller();
        Action action = ctx.action();
        SLog conAnnoLog = null;


        MethodWrap method = action.method();
        SLog annoLog = method.getAnnotation(SLog.class);
        Mapping annoMapping = method.getAnnotation(Mapping.class);
        Log log = new Log();
        log.setIp(ctx.realIp());
        log.setLogStatus(Constant.ENABLE);
        if (ctx.errors!=null) {
            log.setLogStatus(Constant.DISABLE);
            log.setError(ctx.errors.getMessage());
        }
        log.setUrl(ctx.path());
        try {
            log.setResult(ONode.stringify(result));
        } catch (Exception e){
            e.printStackTrace();
        }
        log.setOperParam(ONode.stringify(ctx.paramMap()));
        log.setMethod(controller.getClass().getName() + "." + action.name());
        StringJoiner opSb = new StringJoiner ("-");
        try {
            conAnnoLog = controller.getClass().getAnnotation(SLog.class);
            opSb.add(conAnnoLog.value());
        } catch (Exception e) {
        }
        if (annoLog!=null) {
            opSb.add(annoLog.value());
            if ("".equals(annoLog.value()) && annoMapping!=null) {
                opSb.add(Constant.OPERAMAP.get(annoMapping.value()));
            }
        }
        log.setBusinessName(opSb.toString());
        logService.save(log);
        return result;
    }
}
